<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport"
          content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,viewport-fit=cover">
    <meta name="format-detection" content="telephone=no">
    <style type="text/css">

#watermark {

  position: relative;
  overflow: hidden;
}

#watermark .x {
  position: absolute;
  top: 800;
  left: 400;
  color: #3300ff;
  font-size: 50px;
  pointer-events: none;
  opacity:0.3;
  filter:Alpha(opacity=50);
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
}
    </style>


    <style type="text/css">
 html{color:#333;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;text-rendering:optimizelegibility;font-family:Helvetica Neue,PingFang SC,Verdana,Microsoft Yahei,Hiragino Sans GB,Microsoft Sans Serif,WenQuanYi Micro Hei,sans-serif}html.borderbox *,html.borderbox :after,html.borderbox :before{box-sizing:border-box}article,aside,blockquote,body,button,code,dd,details,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hr,input,legend,li,menu,nav,ol,p,pre,section,td,textarea,th,ul{margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,menu,nav,section{display:block}audio,canvas,video{display:inline-block}body,button,input,select,textarea{font:300 1em/1.8 PingFang SC,Lantinghei SC,Microsoft Yahei,Hiragino Sans GB,Microsoft Sans Serif,WenQuanYi Micro Hei,Helvetica,sans-serif}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}table{border-collapse:collapse;border-spacing:0}fieldset,img{border:0}blockquote{position:relative;color:#999;font-weight:400;border-left:1px solid #1abc9c;padding-left:1em;margin:1em 3em 1em 2em}@media only screen and (max-width:640px){blockquote{margin:1em 0}}abbr,acronym{border-bottom:1px dotted;font-variant:normal}abbr{cursor:help}del{text-decoration:line-through}address,caption,cite,code,dfn,em,th,var{font-style:normal;font-weight:400}ol,ul{list-style:none}caption,th{text-align:left}q:after,q:before{content:""}sub,sup{font-size:75%;line-height:0;position:relative}:root sub,:root sup{vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}a{color:#1abc9c}a:hover{text-decoration:underline}.typo a{border-bottom:1px solid #1abc9c}.typo a:hover{border-bottom-color:#555;color:#555}.typo a:hover,a,ins{text-decoration:none}.typo-u,u{text-decoration:underline}mark{background:#fffdd1;border-bottom:1px solid #ffedce;padding:2px;margin:0 5px}code,pre,pre tt{font-family:Courier,Courier New,monospace}pre{background:hsla(0,0%,97%,.7);border:1px solid #ddd;padding:1em 1.5em;display:block;-webkit-overflow-scrolling:touch}hr{border:none;border-bottom:1px solid #cfcfcf;margin-bottom:.8em;height:10px}.typo-small,figcaption,small{font-size:.9em;color:#888}b,strong{font-weight:700;color:#000}[draggable]{cursor:move}.clearfix:after,.clearfix:before{content:"";display:table}.clearfix:after{clear:both}.clearfix{zoom:1}.textwrap,.textwrap td,.textwrap th{word-wrap:break-word;word-break:break-all}.textwrap-table{table-layout:fixed}.serif{font-family:Palatino,Optima,Georgia,serif}.typo-dl,.typo-form,.typo-hr,.typo-ol,.typo-p,.typo-pre,.typo-table,.typo-ul,.typo dl,.typo form,.typo hr,.typo ol,.typo p,.typo pre,.typo table,.typo ul,blockquote{margin-bottom:1rem}h1,h2,h3,h4,h5,h6{font-family:PingFang SC,Helvetica Neue,Verdana,Microsoft Yahei,Hiragino Sans GB,Microsoft Sans Serif,WenQuanYi Micro Hei,sans-serif;color:#000;line-height:1.35}.typo-h1,.typo-h2,.typo-h3,.typo-h4,.typo-h5,.typo-h6,.typo h1,.typo h2,.typo h3,.typo h4,.typo h5,.typo h6{margin-top:1.2em;margin-bottom:.6em;line-height:1.35}.typo-h1,.typo h1{font-size:2em}.typo-h2,.typo h2{font-size:1.8em}.typo-h3,.typo h3{font-size:1.6em}.typo-h4,.typo h4{font-size:1.4em}.typo-h5,.typo-h6,.typo h5,.typo h6{font-size:1.2em}.typo-ul,.typo ul{margin-left:1.3em;list-style:disc}.typo-ol,.typo ol{list-style:decimal;margin-left:1.9em}.typo-ol ol,.typo-ol ul,.typo-ul ol,.typo-ul ul,.typo li ol,.typo li ul{margin-bottom:.8em;margin-left:2em}.typo-ol ul,.typo-ul ul,.typo li ul{list-style:circle}.typo-table td,.typo-table th,.typo table caption,.typo table td,.typo table th{border:1px solid #ddd;padding:.5em 1em;color:#666}.typo-table th,.typo table th{background:#fbfbfb}.typo-table thead th,.typo table thead th{background:hsla(0,0%,95%,.7)}.typo table caption{border-bottom:none}.typo-input,.typo-textarea{-webkit-appearance:none;border-radius:0}.typo-em,.typo em,caption,legend{color:#000;font-weight:inherit}.typo-em{position:relative}.typo-em:after{position:absolute;top:.65em;left:0;width:100%;overflow:hidden;white-space:nowrap;content:"\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB\30FB"}.typo img{max-width:100%}.common-content{font-weight:400;color:#353535;line-height:1.75rem;white-space:normal;word-break:normal;font-size:1rem}.common-content img{display:block;max-width:100%;background-color:#eee}.common-content audio,.common-content video{width:100%;background-color:#eee}.common-content center,.common-content font{margin-top:1rem;display:inline-block}.common-content center{width:100%}.common-content pre{margin-top:1rem;padding-left:0;padding-right:0;position:relative;overflow:hidden}.common-content pre code{font-size:.8rem;font-family:Consolas,Liberation Mono,Menlo,monospace,Courier;display:block;width:100%;box-sizing:border-box;padding-left:1rem;padding-right:1rem;overflow-x:auto}.common-content hr{border:none;margin-top:1.5rem;margin-bottom:1.5rem;border-top:1px solid #f5f5f5;height:1px;background:none}.common-content b,.common-content h1,.common-content h2,.common-content h3,.common-content h4,.common-content h5,.common-content strong{font-weight:700}.common-content h1,.common-content h2{font-size:1.125rem;margin-bottom:.45rem}.common-content h3,.common-content h4,.common-content h5{font-size:1rem;margin-bottom:.45rem}.common-content p{font-weight:400;color:#353535;margin-top:.15rem}.common-content .orange{color:#ff5a05}.common-content .reference{font-size:1rem;color:#888}.custom-rich-content h1{margin-top:0;font-weight:400;font-size:15.25px;border-bottom:1px solid #eee;line-height:2.8}.custom-rich-content li,.custom-rich-content p{font-size:14px;color:#888;line-height:1.6}table.hljs-ln{margin-bottom:0;border-spacing:0;border-collapse:collapse}table.hljs-ln,table.hljs-ln tbody,table.hljs-ln td,table.hljs-ln tr{box-sizing:border-box}table.hljs-ln td{padding:0;border:0}table.hljs-ln td.hljs-ln-numbers{min-width:15px;color:rgba(27,31,35,.3);text-align:right;white-space:nowrap;cursor:pointer;user-select:none}table.hljs-ln td.hljs-ln-code,table.hljs-ln td.hljs-ln-numbers{font-family:SFMono-Regular,Consolas,Liberation Mono,Menlo,Courier,monospace;font-size:12px;line-height:20px;vertical-align:top}table.hljs-ln td.hljs-ln-code{position:relative;padding-right:10px;padding-left:10px;overflow:visible;color:#24292e;word-wrap:normal;white-space:pre}video::-webkit-media-controls{overflow:hidden!important}video::-webkit-media-controls-enclosure{width:calc(100% + 32px);margin-left:auto}.button-cancel{color:#888;border:1px solid #888;border-radius:3px;margin-right:12px}.button-cancel,.button-primary{-ms-flex-positive:1;flex-grow:1;height:35px;display:inline-block;font-size:15px;text-align:center;line-height:36px}.button-primary{color:#fff;background-color:#ff5a05;border-radius:3px}@font-face{font-family:iconfont;src:url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.eot);src:url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.eot#iefix) format("embedded-opentype"),url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.woff) format("woff"),url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.ttf) format("truetype"),url(//at.alicdn.com/t/font_372689_bwwwtosxtzp.svg#iconfont) format("svg")}@font-face{font-family:player-font;src:url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.eot);src:url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.eot#iefix) format("embedded-opentype"),url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.woff) format("woff"),url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.ttf) format("truetype"),url(//at.alicdn.com/t/font_509397_1cyjv4o90qiod2t9.svg#player-font) format("svg")}.iconfont{font-family:iconfont!important;font-size:16px;font-style:normal;-webkit-font-smoothing:antialiased;-webkit-text-stroke-width:.2px;-moz-osx-font-smoothing:grayscale}html{background:#fff;min-height:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{width:100%}body.fixed{overflow:hidden;position:fixed;width:100vw;height:100vh}i{font-style:normal}a{word-wrap:break-word;-webkit-tap-highlight-color:rgba(0,0,0,0)}a:hover{text-decoration:none}.fade-enter-active,.fade-leave-active{transition:opacity .3s}.fade-enter,.fade-leave-to{opacity:0}.MathJax,.MathJax_CHTML,.MathJax_MathContainer,.MathJax_MathML,.MathJax_PHTML,.MathJax_PlainSource,.MathJax_SVG{outline:0}.ios-app-switch .js-audit{display:none}._loading_wrap_{position:fixed;width:100vw;height:100vh;top:50%;left:50%;transform:translate(-50%,-50%);z-index:999}._loading_div_class_,._loading_wrap_{display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;-ms-flex-align:center;align-items:center}._loading_div_class_{word-wrap:break-word;padding:.5rem .75rem;text-align:center;z-index:9999;font-size:.6rem;max-width:60%;color:#fff;border-radius:.25rem;-ms-flex-direction:column;flex-direction:column}._loading_div_class_ .message{color:#353535;font-size:16px;line-height:3}.spinner{animation:circle-rotator 1.4s linear infinite}.spinner *{line-height:0;box-sizing:border-box}@keyframes circle-rotator{0%{transform:rotate(0deg)}to{transform:rotate(270deg)}}.path{stroke-dasharray:187;stroke-dashoffset:0;transform-origin:center;animation:circle-dash 1.4s ease-in-out infinite,circle-colors 5.6s ease-in-out infinite}@keyframes circle-colors{0%{stroke:#ff5a05}to{stroke:#ff5a05}}@keyframes circle-dash{0%{stroke-dashoffset:187}50%{stroke-dashoffset:46.75;transform:rotate(135deg)}to{stroke-dashoffset:187;transform:rotate(450deg)}}.confirm-box-wrapper,.confirm-box-wrapper .mask{position:absolute;top:0;left:0;right:0;bottom:0}.confirm-box-wrapper .mask{background:rgba(0,0,0,.6)}.confirm-box-wrapper .confirm-box{position:fixed;top:50%;left:50%;width:267px;background:#fff;transform:translate(-50%,-50%);border-radius:7px}.confirm-box-wrapper .confirm-box .head{margin:0 18px;font-size:18px;text-align:center;line-height:65px;border-bottom:1px solid #d9d9d9}.confirm-box-wrapper .confirm-box .body{padding:18px;padding-bottom:0;color:#353535;font-size:12.5px;max-height:150px;overflow:auto}.confirm-box-wrapper .confirm-box .foot{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;padding:18px}.confirm-box-wrapper .confirm-box .foot .button-cancel{border:1px solid #d9d9d9}.hljs{display:block;overflow-x:auto;padding:.5em;color:#333;background:#f8f8f8}.hljs-comment,.hljs-quote{color:#998;font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-subst{color:#333;font-weight:700}.hljs-literal,.hljs-number,.hljs-tag .hljs-attr,.hljs-template-variable,.hljs-variable{color:teal}.hljs-doctag,.hljs-string{color:#d14}.hljs-section,.hljs-selector-id,.hljs-title{color:#900;font-weight:700}.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type{color:#458;font-weight:700}.hljs-attribute,.hljs-name,.hljs-tag{color:navy;font-weight:400}.hljs-link,.hljs-regexp{color:#009926}.hljs-bullet,.hljs-symbol{color:#990073}.hljs-built_in,.hljs-builtin-name{color:#0086b3}.hljs-meta{color:#999;font-weight:700}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}




    </style>
    <style type="text/css">
        .button-cancel[data-v-87ffcada]{color:#888;border:1px solid #888;border-radius:3px;margin-right:12px}.button-cancel[data-v-87ffcada],.button-primary[data-v-87ffcada]{-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;height:35px;display:inline-block;font-size:15px;text-align:center;line-height:36px}.button-primary[data-v-87ffcada]{color:#fff;background-color:#ff5a05;border-radius:3px}.pd[data-v-87ffcada]{padding-left:1.375rem;padding-right:1.375rem}.article[data-v-87ffcada]{max-width:70rem;margin:0 auto}.article .article-unavailable[data-v-87ffcada]{color:#fa8919;font-size:15px;font-weight:600;line-height:24px;border-radius:5px;padding:12px;background-color:#f6f7fb;margin-top:20px}.article .article-unavailable .iconfont[data-v-87ffcada]{font-size:12px}.article .main[data-v-87ffcada]{padding:1.25rem 0;margin-bottom:52px}.article-title[data-v-87ffcada]{color:#353535;font-weight:400;line-height:1.65rem;font-size:1.34375rem}.article-info[data-v-87ffcada]{color:#888;font-size:.9375rem;margin-top:1.0625rem}.article-content[data-v-87ffcada]{margin-top:1.0625rem}.article-content.android video[data-v-87ffcada]::-webkit-media-controls-fullscreen-button{display:none}.copyright[data-v-87ffcada]{color:#b2b2b2;padding-bottom:20px;margin-top:20px;font-size:13px}.audio-player[data-v-87ffcada]{width:100%;margin:20px 0}.to-comment[data-v-87ffcada]{overflow:hidden;padding-top:10px;margin-bottom:-30px}.to-comment a.button-primary[data-v-87ffcada]{float:right;height:20px;font-size:12px;line-height:20px;padding:4px 8px;cursor:pointer}.article-comments[data-v-87ffcada]{margin-top:2rem}.article-comments h2[data-v-87ffcada]{text-align:center;color:#888;position:relative;z-index:1;margin-bottom:1rem}.article-comments h2[data-v-87ffcada]:before{border-top:1px dotted #888;content:"";position:absolute;top:56%;left:0;width:100%;z-index:-1}.article-comments h2 span[data-v-87ffcada]{font-size:15.25px;font-weight:400;padding:0 1rem;background:#fff;display:inline-block}.article-sub-bottom[data-v-87ffcada]{z-index:10;cursor:pointer}.switch-btns[data-v-87ffcada]{height:76px;cursor:pointer;padding-top:24px;padding-bottom:24px;border-bottom:10px solid #f6f7fb;position:relative}.switch-btns[data-v-87ffcada]:before{content:" ";height:1px;background:#e8e8e8;position:absolute;top:0;left:0;-webkit-box-sizing:border-box;box-sizing:border-box;left:1.375rem;right:1.375rem}.switch-btns .btn[data-v-87ffcada]{height:38px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.switch-btns .btn .tag[data-v-87ffcada]{-webkit-box-flex:0;-ms-flex:0 0 62px;flex:0 0 62px;text-align:center;color:#888;font-size:14px;border-radius:10px;height:22px;line-height:22px;background:#f6f7fb;font-weight:400}.switch-btns .btn .txt[data-v-87ffcada]{margin-left:10px;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;color:#888;font-size:15px;height:22px;line-height:22px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:400}@media (max-width:769px){.article .breadcrumb[data-v-87ffcada]{padding-top:10px;padding-bottom:10px}}





    </style>

    <style type="text/css">
        .comment-item{list-style-position:inside;width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;margin-bottom:1rem}.comment-item a{border-bottom:none}.comment-item .avatar{width:2.625rem;height:2.625rem;-ms-flex-negative:0;flex-shrink:0;border-radius:50%}.comment-item .info{margin-left:.5rem;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1}.comment-item .info .hd{width:100%;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.comment-item .info .hd .username{color:#888;font-size:15.25px;font-weight:400;line-height:1.2}.comment-item .info .hd .control{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.comment-item .info .hd .control .btn-share{color:#888;font-size:.75rem;margin-right:1rem}.comment-item .info .hd .control .btn-praise{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-align:center;-ms-flex-align:center;align-items:center;font-size:15.25px;text-decoration:none}.comment-item .info .hd .control .btn-praise i{color:#888;display:inline-block;font-size:.75rem;margin-right:.3rem;margin-top:-.01rem}.comment-item .info .hd .control .btn-praise i.on,.comment-item .info .hd .control .btn-praise span{color:#ff5a05}.comment-item .info .bd{color:#353535;font-size:15.25px;font-weight:400;white-space:normal;word-break:break-all;line-height:1.6}.comment-item .info .time{color:#888;font-size:9px;line-height:1}.comment-item .info .reply .reply-hd{font-size:15.25px}.comment-item .info .reply .reply-hd span{margin-left:-12px;color:#888;font-weight:400}.comment-item .info .reply .reply-hd i{color:#ff5a05;font-size:15.25px}.comment-item .info .reply .reply-content{color:#353535;font-size:15.25px;font-weight:400;white-space:normal;word-break:break-all}.comment-item .info .reply .reply-time{color:#888;font-size:9px}




    </style>
</head>
<body>
<div id="app">


    <div data-v-87ffcada="" class="article" id="watermark">
        <p class="x">更多课程请加QQ群170701297</p>
        <div data-v-87ffcada="" class="main main-app">
            <h1 data-v-87ffcada="" class="article-title pd">
                21讲套路篇：如何“快准狠”找到系统内存的问题
            </h1>
            <div data-v-87ffcada="" class="article-content typo common-content pd"><img data-v-87ffcada=""
                                                                                        src="https://static001.geekbang.org/resource/image/a9/64/a95962cbd68e8fa648e708851e2b9f64.jpg">


                <div data-v-87ffcada="" id="article-content" class="">
                    <div class="text">
                        <p>你好，我是倪朋飞。</p><p>前几节，通过几个案例，我们分析了各种常见的内存性能问题。我相信通过它们，你对内存的性能分析已经有了基本的思路，也熟悉了很多分析内存性能的工具。你肯定会想，有没有迅速定位内存问题的方法？当定位出内存的瓶颈后，又有哪些优化内存的思路呢？</p><p>今天，我就来帮你梳理一下，怎样可以快速定位系统内存，并且总结了相关的解决思路。</p><h2>内存性能指标</h2><p>为了分析内存的性能瓶颈，首先你要知道，怎样衡量内存的性能，也就是性能指标问题。我们先来回顾一下，前几节学过的内存性能指标。</p><p>你可以自己先找张纸，凭着记忆写一写；或者打开前面的文章，自己总结一下。</p><p>首先，你最容易想到的是系统内存使用情况，比如已用内存、剩余内存、共享内存、可用内存、缓存和缓冲区的用量等。</p><ul>
<li>
<p>已用内存和剩余内存很容易理解，就是已经使用和还未使用的内存。</p>
</li>
<li>
<p>共享内存是通过tmpfs实现的，所以它的大小也就是tmpfs使用的内存大小。tmpfs其实也是一种特殊的缓存。</p>
</li>
<li>
<p>可用内存是新进程可以使用的最大内存，它包括剩余内存和可回收缓存。</p>
</li>
<li>
<p>缓存包括两部分，一部分是磁盘读取文件的页缓存，用来缓存从磁盘读取的数据，可以加快以后再次访问的速度。另一部分，则是Slab分配器中的可回收内存。</p>
</li>
<li>
<p>缓冲区是对原始磁盘块的临时存储，用来缓存将要写入磁盘的数据。这样，内核就可以把分散的写集中起来，统一优化磁盘写入。</p>
</li>
</ul><!-- [[[read_end]]] --><p>第二类很容易想到的，应该是进程内存使用情况，比如进程的虚拟内存、常驻内存、共享内存以及Swap内存等。</p><ul>
<li>
<p>虚拟内存，包括了进程代码段、数据段、共享内存、已经申请的堆内存和已经换出的内存等。这里要注意，已经申请的内存，即使还没有分配物理内存，也算作虚拟内存。</p>
</li>
<li>
<p>常驻内存是进程实际使用的物理内存，不过，它不包括Swap和共享内存。</p>
</li>
<li>
<p>共享内存，既包括与其他进程共同使用的真实的共享内存，还包括了加载的动态链接库以及程序的代码段等。</p>
</li>
<li>
<p>Swap内存，是指通过Swap换出到磁盘的内存。</p>
</li>
</ul><p>当然，这些指标中，常驻内存一般会换算成占系统总内存的百分比，也就是进程的内存使用率。</p><p>除了这些很容易想到的指标外，我还想再强调一下，缺页异常。</p><p>在内存分配的原理中，我曾经讲到过，系统调用内存分配请求后，并不会立刻为其分配物理内存，而是在请求首次访问时，通过缺页异常来分配。缺页异常又分为下面两种场景。</p><ul>
<li>
<p>可以直接从物理内存中分配时，被称为次缺页异常。</p>
</li>
<li>
<p>需要磁盘I/O介入（比如Swap）时，被称为主缺页异常。</p>
</li>
</ul><p>显然，主缺页异常升高，就意味着需要磁盘I/O，那么内存访问也会慢很多。</p><p>除了系统内存和进程内存，第三类重要指标就是Swap的使用情况，比如Swap的已用空间、剩余空间、换入速度和换出速度等。</p><ul>
<li>
<p>已用空间和剩余空间很好理解，就是字面上的意思，已经使用和没有使用的内存空间。</p>
</li>
<li>
<p>换入和换出速度，则表示每秒钟换入和换出内存的大小。</p>
</li>
</ul><p>这些内存的性能指标都需要我们熟记并且会用，我把它们汇总成了一个思维导图，你可以保存打印出来，或者自己仿照着总结一份。</p><p><img src="https://static001.geekbang.org/resource/image/e2/36/e28cf90f0b137574bca170984d1e6736.png" alt=""></p><h2>内存性能工具</h2><p>了解了内存的性能指标，我们还得知道，怎么才能获得这些指标，也就是会用性能工具。这里，我们也用同样的方法，回顾一下前面案例中已经用到的各种内存性能工具。 还是鼓励你先自己回忆和总结一下。</p><p>首先，你应该注意到了，所有的案例中都用到了free。这是个最常用的内存工具，可以查看系统的整体内存和Swap使用情况。相对应的，你可以用top或ps，查看进程的内存使用情况。</p><p>然后，在缓存和缓冲区的原理篇中，我们通过proc文件系统，找到了内存指标的来源；并通过vmstat，动态观察了内存的变化情况。与free相比，vmstat除了可以动态查看内存变化，还可以区分缓存和缓冲区、Swap换入和换出的内存大小。</p><p>接着，在缓存和缓冲区的案例篇中，为了弄清楚缓存的命中情况，我们又用了cachestat ，查看整个系统缓存的读写命中情况，并用 cachetop 来观察每个进程缓存的读写命中情况。</p><p>再接着，在内存泄漏的案例中，我们用vmstat，发现了内存使用在不断增长，又用memleak，确认发生了内存泄漏。通过memleak给出的内存分配栈，我们找到了内存泄漏的可疑位置。</p><p>最后，在Swap的案例中，我们用sar发现了缓冲区和Swap升高的问题。通过cachetop，我们找到了缓冲区升高的根源；通过对比剩余内存跟/proc/zoneinfo的内存阈，我们发现Swap升高是内存回收导致的。案例最后，我们还通过/proc文件系统，找出了Swap所影响的进程。</p><p>到这里，你是不是再次感觉到了来自性能世界的“恶意”。性能工具怎么那么多呀？其实，还是那句话，理解内存的工作原理，结合性能指标来记忆，拿下工具的使用方法并不难。</p><h2>性能指标和工具的联系</h2><p>同CPU性能分析一样，我的经验是两个不同维度出发，整理和记忆。</p><ul>
<li>
<p>从内存指标出发，更容易把工具和内存的工作原理关联起来。</p>
</li>
<li>
<p>从性能工具出发，可以更快地利用工具，找出我们想观察的性能指标。特别是在工具有限的情况下，我们更得充分利用手头的每一个工具，挖掘出更多的问题。</p>
</li>
</ul><p>同样的，根据内存性能指标和工具的对应关系，我做了两个表格，方便你梳理关系和理解记忆。当然，你也可以当成“指标工具”和“工具指标”指南来用，在需要时直接查找。</p><p>第一个表格，从内存指标出发，列举了哪些性能工具可以提供这些指标。这样，在实际排查性能问题时，你就可以清楚知道，究竟要用什么工具来辅助分析，提供你想要的指标。</p><p><img src="https://static001.geekbang.org/resource/image/8f/ed/8f477035fc4348a1f80bde3117a7dfed.png" alt=""></p><p>第二个表格，从性能工具出发，整理了这些常见工具能提供的内存指标。掌握了这个表格，你可以最大化利用已有的工具，尽可能多地找到你要的指标。</p><p>这些工具的具体使用方法并不用背，你只要知道有哪些可用的工具，以及这些工具提供的基本指标。真正用到时， man 一下查它们的使用手册就可以了。</p><p><img src="https://static001.geekbang.org/resource/image/52/9b/52bb55fba133401889206d02c224769b.png" alt=""></p><h2>如何迅速分析内存的性能瓶颈</h2><p>我相信到这一步，你对内存的性能指标已经非常熟悉，也清楚每种性能指标分别能用什么工具来获取。</p><p>那是不是说，每次碰到内存性能问题，你都要把上面这些工具全跑一遍，然后再把所有内存性能指标全分析一遍呢？</p><p>自然不是。前面的CPU性能篇我们就说过，简单查找法，虽然是有用的，也很可能找到某些系统潜在瓶颈。但是这种方法的低效率和大工作量，让我们首先拒绝了这种方法。</p><p>还是那句话，在实际生产环境中，我们希望的是，尽可能<strong>快</strong>地定位系统瓶颈，然后尽可能<strong>快</strong>地优化性能，也就是要又快又准地解决性能问题。</p><p>那有没有什么方法，可以又快又准地分析出系统的内存问题呢？</p><p>方法当然有。还是那个关键词，找关联。其实，虽然内存的性能指标很多，但都是为了描述内存的原理，指标间自然不会完全孤立，一般都会有关联。当然，反过来说，这些关联也正是源于系统的内存原理，这也是我总强调基础原理的重要性，并在文章中穿插讲解。</p><p>举个最简单的例子，当你看到系统的剩余内存很低时，是不是就说明，进程一定不能申请分配新内存了呢？当然不是，因为进程可以使用的内存，除了剩余内存，还包括了可回收的缓存和缓冲区。</p><p>所以，<strong>为了迅速定位内存问题，我通常会先运行几个覆盖面比较大的性能工具，比如free、top、vmstat、pidstat等</strong>。</p><p>具体的分析思路主要有这几步。</p><ol>
<li>
<p>先用free和top，查看系统整体的内存使用情况。</p>
</li>
<li>
<p>再用vmstat和pidstat，查看一段时间的趋势，从而判断出内存问题的类型。</p>
</li>
<li>
<p>最后进行详细分析，比如内存分配分析、缓存/缓冲区分析、具体进程的内存使用分析等。</p>
</li>
</ol><p>同时，我也把这个分析过程画成了一张流程图，你可以保存并打印出来使用。</p><p><img src="https://static001.geekbang.org/resource/image/d7/fe/d79cd017f0c90b84a36e70a3c5dccffe.png" alt=""></p><p>图中列出了最常用的几个内存工具，和相关的分析流程。其中，箭头表示分析的方向，举几个例子你可能会更容易理解。</p><p>第一个例子，当你通过free，发现大部分内存都被缓存占用后，可以使用vmstat或者sar观察一下缓存的变化趋势，确认缓存的使用是否还在继续增大。</p><p>如果继续增大，则说明导致缓存升高的进程还在运行，那你就能用缓存/缓冲区分析工具（比如cachetop、slabtop等），分析这些缓存到底被哪里占用。</p><p>第二个例子，当你free一下，发现系统可用内存不足时，首先要确认内存是否被缓存/缓冲区占用。排除缓存/缓冲区后，你可以继续用pidstat或者top，定位占用内存最多的进程。</p><p>找出进程后，再通过进程内存空间工具（比如pmap），分析进程地址空间中内存的使用情况就可以了。</p><p>第三个例子，当你通过vmstat或者sar发现内存在不断增长后，可以分析中是否存在内存泄漏的问题。</p><p>比如你可以使用内存分配分析工具 memleak ，检查是否存在内存泄漏。如果存在内存泄漏问题，memleak会为你输出内存泄漏的进程以及调用堆栈。</p><p>注意，这个图里我没有列出所有性能工具，只给出了最核心的几个。这么做，一方面，确实不想让大量的工具列表吓到你。</p><p>另一方面，希望你能把重心先放在核心工具上，通过我提供的案例和真实环境的实践，掌握使用方法和分析思路。 毕竟熟练掌握它们，你就可以解决大多数的内存问题。</p><h2>小结</h2><p>在今天的文章中，我带你回顾了常见的内存性能指标，梳理了常见的内存性能分析工具，最后还总结了快速分析内存问题的思路。</p><p>虽然内存的性能指标和性能工具都挺多，但理解了内存管理的基本原理后，你会发现它们其实都有一定的关联。梳理出它们的关系，掌握内存分析的套路并不难。</p><p>找到内存问题的来源后，下一步就是相应的优化工作了。在我看来，内存调优最重要的就是，保证应用程序的热点数据放到内存中，并尽量减少换页和交换。</p><p>常见的优化思路有这么几种。</p><ol>
<li>
<p>最好禁止 Swap。如果必须开启Swap，降低swappiness的值，减少内存回收时Swap的使用倾向。</p>
</li>
<li>
<p>减少内存的动态分配。比如，可以使用内存池、大页（HugePage）等。</p>
</li>
<li>
<p>尽量使用缓存和缓冲区来访问数据。比如，可以使用堆栈明确声明内存空间，来存储需要缓存的数据；或者用Redis 这类的外部缓存组件，优化数据的访问。</p>
</li>
<li>
<p>使用cgroups等方式限制进程的内存使用情况。这样，可以确保系统内存不会被异常进程耗尽。</p>
</li>
<li>
<p>通过 /proc/pid/oom_adj ，调整核心应用的oom_score。这样，可以保证即使内存紧张，核心应用也不会被OOM杀死。</p>
</li>
</ol><h2>思考</h2><p>由于篇幅限制，我在这里只列举了一些我认为的重要内存指标和分析思路。我想，你肯定也碰到过很多内存相关的性能问题。所以，我想请你来聊一聊，你处理过的内存性能问题，你是怎样分析它的瓶颈并解决的呢？这个过程中，遇到了什么坑，或者有什么重要收获吗？</p><p>欢迎在留言区跟我讨论，也欢迎把这篇文章分享给你的同事、朋友。我们一起在实战中演练，在交流中进步。</p><p><img src="https://static001.geekbang.org/resource/image/a3/e9/a396aed4116c2c989771c1295736abe9.jpg" alt=""></p>
                    </div>
                </div>

            </div>
            <div data-v-87ffcada="" class="article-comments pd"><h2 data-v-87ffcada=""><span
                    data-v-87ffcada="">精选留言</span></h2>
                <ul data-v-87ffcada="">
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="https://static001.geekbang.org/account/avatar/00/10/d2/ed/e9158538.jpg" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">减肥的老郭</span>
                            </div>
                            <div class="bd">老师好，文中提到的bcc相关的工具都需要版本较高的内核，但是真实生产都无法满足这个要求，有别的替代工具么？ <br></div>
                            <span class="time">2019-01-07 11:03</span>
                            
                            <div class="reply">
                                <div class="reply-hd"><span>作者回复</span></div>
                                <p class="reply-content">有的，比如内存泄漏使用valgrind、动态跟踪使用systemtap等。这些工具相对来说更难用一些</p>
                                <p class="reply-time">2019-01-07 17:38</p>
                            </div>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="https://static001.geekbang.org/account/avatar/00/14/11/4b/afafe35e.jpg" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">xfan</span>
                            </div>
                            <div class="bd">打卡<br> <br></div>
                            <span class="time">2019-01-12 11:40</span>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="https://static001.geekbang.org/account/avatar/00/11/42/18/edc1b373.jpg" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">风飘，吾独思</span>
                            </div>
                            <div class="bd">打卡 <br></div>
                            <span class="time">2019-01-09 08:44</span>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">划时代</span>
                            </div>
                            <div class="bd">打卡总结 <br></div>
                            <span class="time">2019-01-08 09:53</span>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="https://static001.geekbang.org/account/avatar/00/0f/5f/fc/6ddfb5d5.jpg" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">忍…善</span>
                            </div>
                            <div class="bd">老师，如果是swap缓慢的增长该如何分析呢，每天几十M的速度，sar vmstat几乎看不到si so，程序跑了一个月增长了一个g swap <br></div>
                            <span class="time">2019-01-08 09:52</span>
                            
                            <div class="reply">
                                <div class="reply-hd"><span>作者回复</span></div>
                                <p class="reply-content">上监控系统，各种内存指标增长的趋势是可以看到的</p>
                                <p class="reply-time">2019-01-09 18:11</p>
                            </div>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="https://static001.geekbang.org/account/avatar/00/0f/de/bf/4df4224d.jpg" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">shuifa</span>
                            </div>
                            <div class="bd">打卡，学习是一种习惯 <br></div>
                            <span class="time">2019-01-07 23:18</span>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">无名老卒</span>
                            </div>
                            <div class="bd">老师能不能举一些实际的例子，我是有遇到过线上内存泄露的案例，每次出现这个问题时，基本上是无解，因为基本上都是直接宕机了。这个可有监控方法？<br><br>其他的内存使用上的问题，如缺页、缓存数据用得过多等异常，基本上没有遇到过，这类问题，老师遇到的次数多吗？ <br></div>
                            <span class="time">2019-01-07 22:18</span>
                            
                            <div class="reply">
                                <div class="reply-hd"><span>作者回复</span></div>
                                <p class="reply-content">可以把系统和进程的内存指标监控起来，这样根据历史趋势就可以知道是哪些进程内存泄漏了。<br><br>其他的这些也有，但比较少。实际进程基本上都有一个内存管理模块，统一管理内存。有问题也是这个模块刚开始写的时候比较多，后面就会逐渐稳定起来。</p>
                                <p class="reply-time">2019-01-09 18:19</p>
                            </div>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="https://static001.geekbang.org/account/avatar/00/12/64/05/6989dce6.jpg" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">我来也</span>
                            </div>
                            <div class="bd">[D22打卡]<br>内存的分析方法 和 工具 有了个印象.<br>等遇到了内存方面的性能问题再来精读吧.<br>现在我个人精力有限. 只能先抓重点了. <br>并不是老师的专栏写的不好.😂😂 <br></div>
                            <span class="time">2019-01-07 15:28</span>
                            
                            <div class="reply">
                                <div class="reply-hd"><span>作者回复</span></div>
                                <p class="reply-content">😢</p>
                                <p class="reply-time">2019-01-07 17:35</p>
                            </div>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="https://static001.geekbang.org/account/avatar/00/13/2d/24/28acca15.jpg" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">DJH</span>
                            </div>
                            <div class="bd">倪老师，我们有一个空闲的docker节点（CentOS 7.4，只有k8s node组件，ceph组件和2个空跑的测试pod），平常只有几十的磁盘iops，每隔若干天后系统磁盘的iops就会持续超过3000，并且降不下来。经过iostat检查发现磁盘读写来自于swap卷，奇怪的是系统空闲内存很多，swap使用率也只有一点点（不到1%），主机上也没什么业务。现在每次碰到这个问题只能重启一下解决。请问这种问题有啥解决思路吗？ <br></div>
                            <span class="time">2019-01-07 08:46</span>
                            
                            <div class="reply">
                                <div class="reply-hd"><span>作者回复</span></div>
                                <p class="reply-content">可能跟NUMA配置有关，可以查下是不是允许跨NODE</p>
                                <p class="reply-time">2019-01-07 17:43</p>
                            </div>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="https://static001.geekbang.org/account/avatar/00/14/13/81/f16a0401.jpg" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">大青蛙</span>
                            </div>
                            <div class="bd">沙发 <br></div>
                            <span class="time">2019-01-07 08:27</span>
                            
                        </div>
                    </li>
                    
                    <li data-v-87ffcada="" class="comment-item"><img
                            src="https://wx.qlogo.cn/mmopen/vi_32/PiajxSqBRaEKQMM4m7NHuicr55aRiblTSEWIYe0QqbpyHweaoAbG7j2v7UUElqqeP3Ihrm3UfDPDRb1Hv8LvPwXqA/132" class="avatar">
                        <div class="info">
                            <div class="hd"><span class="username">ninuxer</span>
                            </div>
                            <div class="bd">打卡day22<br>总结篇，紧跟大佬脚步～ <br></div>
                            <span class="time">2019-01-07 08:05</span>
                            
                        </div>
                    </li>
                    


                </ul>
            </div>
        </div>
    </div>
</div>
</body>
</html>